<template>
  <div class="login-container">
    <el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form layui-anim layui-anim-scale">
      <login-title></login-title>
      <el-form-item prop="mobile">
        <span class="svg-container">
          <svg-icon icon-class="user"/>
        </span>
        <el-input v-model="loginForm.mobile" placeholder="请输入手机号"/>
      </el-form-item>
      <el-form-item prop="password">
        <span class="svg-container">
          <svg-icon icon-class="password"/>
        </span>
        <el-input :key="passwordType" ref="password" v-model="loginForm.password" :type="passwordType" placeholder="请输入密码" @keyup.enter.native="handleLogin"/>
        <span class="show-pwd" @click="changePasswordType">
          <svg-icon :icon-class="type"/>
        </span>
      </el-form-item>
      <el-button :loading="loading" type="primary" @click.prevent="handleLogin">登录</el-button>
      <Tips></Tips>
    </el-form>
  </div>
</template>

<script>
import LoginTitle from '@/views/login/components/loginTitle/loginTitle.vue'
import Tips from '@/views/login/components/Tips/Tips.vue'
import { validMobile } from '@/utils/validate'

export default {
  name: 'Login',
  data() {
    /* 自定义校验手机号的回调函数 */
    const validaMobile = (rule, value, callback) => {
      if (!validMobile(value)) return callback(new Error('手机号码格式错误'))
      callback()
    }
    return {
      /* 表单数据对象 */
      loginForm: {
        mobile: process.env.NODE_ENV === 'production' ? '' : '13800000002',
        password: process.env.NODE_ENV === 'production' ? '' : 'hm#qd@23!'
      },
      /* 表单规则对象 */
      loginRules: {
        mobile: [
          { required: true, message: '请输入手机号', trigger: 'blur' },
          { validator: validaMobile, trigger: 'blur' }
        ],
        password: [
          { required: true, message: '请输入密码', trigger: 'blur' },
          { max: 16, min: 6, message: '密码最小为6位最大为16位', trigger: 'blur' }
        ]
      },
      passwordType: 'password',
      loading: false
    }
  },

  methods: {
    /* 用于修改密码框类型的回调函数 */
    changePasswordType() {
      // 三元判断passwordType是不是等于"password"如果是则赋值为""字符串此时密码会是明文，否则为"password"此时密码会进行加密显示
      this.passwordType = this.passwordType === 'password' ? '' : 'password'
      // 获取焦点
      this.$nextTick(() => {
        this.$refs.password.focus()
      })
    },

    /* 点击登录按钮的回调函数 */
    async handleLogin() {
      /*
      *登录的逻辑：
      * 1.当点击登录按钮的时候使用refs获取表单组件实例调用validate()方法,该方法返回的是一个Promise对象(兜底校验通过返回true否则false)
      * 2.如果表单兜底校验通过则dispatch派发一个action携带当前的手机号和密码做为参数发送登录请求此时服务器会返回token需要将token存储Vuex和持久化存储本地(登录请求如果返回的data中success字段为false则会被reject此时会在组件中的catch捕获)
      * 3.登录成功提示用户
      * 4.跳转路由(如果query参数中没有return_url字段则跳转到登录页，否则跳转到return_url的字段)
      * */
      // 开启按钮的loading效果
      this.loading = true
      // validate()对整个表单进行校验的方法，参数为回调函数。该回调函数会在校验结束后被调用并传入两个参数：是否校验成功和未通过校验的字段。若不传入回调函数则会返回一个 promise
      const valid = this.$refs.loginForm.validate().catch(error => error)
      // 表单兜底校验不通过return出去不执行下面的逻辑
      if (!valid) return
      try {
        // dispatch()一个userStore/userLogin的action并且携带当前用户输入的手机号和密码发送请求，该action返回的是一个Promise对象
        const message = await this.$store.dispatch('userStore/userLogin', this.loginForm)
        //  到了await下面的语句则代表此次请求是成功了(因为如果请求失败会直接进入catch不会执行下面的语句) 提示用户登录成功
        this.$message.success(message)
        // 跳转路由
        this.$router.push('/' || this.$route.query.return_url)
      } catch (error) {
        // 如果登录的请求发送失败则会进入catch语句提示用户登录失败
        this.$message.error(error.message)
      } finally {
        // finally语句不管是成功还是失败都会执行的代码块 关闭按钮loading效果
        this.loading = false
      }
    }
  },
  computed: {
    type() {
      return this.passwordType === 'password' ? 'eye' : 'eye-open'
    }
  },
  components: {
    LoginTitle,
    Tips
  }
}
</script>

<style lang="scss">
$bg: #283443;
$light_gray: #68b0fe;
$cursor: #fff;

@supports (-webkit-mask: none) and (not (cater-color: $cursor)) {
  .login-container .el-input input {
    color: $cursor;
  }
}


.login-container {
  .el-input {
    display: inline-block;
    height: 47px;
    width: 85%;

    input {
      background: transparent;
      border: 0px;
      -webkit-appearance: none;
      border-radius: 0px;
      padding: 12px 5px 12px 15px;
      color: $light_gray;
      height: 47px;
      caret-color: $light_gray;


      &::placeholder {
        color: #889aa4;
      }
    }
  }

  .el-form-item {
    border: 1px solid rgba(255, 255, 255, .1);
    background: rgba(255, 255, 255, .7);
    border-radius: 5px;
    color: #454545;

    .el-form-item__error {
      color: #fff !important;
    }
  }
}

</style>

<style lang="scss" scoped>
$bg: #2d3a4b;
$dark_gray: #889aa4;
$light_gray: #eee;
.login-container {
  min-height: 100%;
  width: 100%;
  background: url("~@/assets/images/login.jpg") no-repeat center;
  background-size: cover;
  overflow: hidden;

  .login-form {
    position: relative;
    width: 550px;
    max-width: 100%;
    padding: 160px 35px 0;
    margin: 0 auto;
    overflow: hidden;
  }


  .svg-container {
    padding: 6px 5px 6px 15px;
    color: $dark_gray;
    vertical-align: middle;
    width: 30px;
    display: inline-block;
  }


  .show-pwd {
    position: absolute;
    right: 10px;
    top: 7px;
    font-size: 16px;
    color: $dark_gray;
    cursor: pointer;
    user-select: none;
  }

  .el-button {
    width: 100%;
    height: 64px;
    font-size: 24px;
    font-weight: 600;
    background-color: #407ffe;
    border: 0;

    &:hover {
      background-color: #2d70ec;

    }
  }

}
</style>
